#====================== BEGIN GPL LICENSE BLOCK ============================
#
#  This program is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program.	 If not, see <http://www.gnu.org/licenses/>.
#  All rights reserved.
#
#======================= END GPL LICENSE BLOCK =============================


import bpy
import time
import math

import importlib
from . import bfu_WriteText
importlib.reload(bfu_WriteText)

from . import bfu_Basics
importlib.reload(bfu_Basics)
from .bfu_Basics import *

from . import bfu_Utils
importlib.reload(bfu_Utils)
from .bfu_Utils import *

def ApplyProxyData(obj):
	
	#Apphy proxy data if needed.
	if obj.ExportProxyChild is not None:
		
		def ReasignProxySkeleton(newArmature, oldArmature):
			for select in bpy.context.selected_objects:
				if select.type == "CURVE":
					for mod in select.modifiers:
						if mod.type == "HOOK":
							if mod.object == oldArmature:
								matrix_inverse = mod.matrix_inverse.copy()
								mod.object = newArmature
								mod.matrix_inverse = matrix_inverse
				
				else:
					for mod in select.modifiers:
						if mod.type == 'ARMATURE':
							if mod.object == oldArmature:
								mod.object = newArmature
			
			for bone in newArmature.pose.bones:
				for cons in bone.constraints:
					if hasattr(cons, 'target'):
						if cons.target == oldArmature:
							cons.target = newArmature
						else:
							NewChildProxyName = cons.target.name+"_UEProxyChild"
							if NewChildProxyName in bpy.data.objects:
								cons.target = bpy.data.objects[NewChildProxyName]




		#Get old armature
		OldProxyChildArmature = None
		for selectedObj in bpy.context.selected_objects:
			if selectedObj != obj:
				if selectedObj.type == "ARMATURE":
					OldProxyChildArmature = selectedObj
				
		if OldProxyChildArmature is not None:
			
			#Re set parent + add to remove	
			ToRemove = []
			for selectedObj in bpy.context.selected_objects:
				if selectedObj != obj:
					if selectedObj.parent == OldProxyChildArmature:
						SavedPos = selectedObj.matrix_world.copy()
						selectedObj.name += "_UEProxyChild"
						selectedObj.parent = obj
						selectedObj.matrix_world = SavedPos
					else:
						ToRemove.append(selectedObj)
			
			ReasignProxySkeleton(obj, OldProxyChildArmature)
					

		

							

			
			SavedSelect = GetCurrentSelect()
			SetCurrentSelect([OldProxyChildArmature, ToRemove])
			bpy.ops.object.delete()
			SetCurrentSelect(SavedSelect)				


def BakeArmatureAnimation(armature, frame_start, frame_end):
	#Change to pose mode
	SavedSelect = GetCurrentSelect()
	bpy.ops.object.select_all(action='DESELECT')
	SelectSpecificObject(armature)
	bpy.ops.nla.bake(frame_start=frame_start-10, frame_end=frame_end+10, only_selected=False, visual_keying=True, clear_constraints=True, bake_types={'POSE'})
	bpy.ops.object.select_all(action='DESELECT')
	SetCurrentSelect(SavedSelect)	

	
def DuplicateSelect():
	
	scene = bpy.context.scene
	#Need look for a optimized duplicate, This is too long
	bpy.ops.object.duplicate()

	currentSelectNames = []
	for currentSelectName in bpy.context.selected_objects:
		currentSelectNames.append(currentSelectName.name)

	bpy.ops.object.duplicates_make_real(use_base_parent=True, use_hierarchy=True)

	for objSelect in currentSelectNames:
		if objSelect not in bpy.context.selected_objects:
			bpy.data.objects[objSelect].select_set(True)
			
	for objScene in bpy.context.selected_objects:
		if objScene.data is not None:
			objScene.data = objScene.data.copy()

def SetSocketsExportTransform(obj):
	#Set socket scale for Unreal
	
	addon_prefs = bpy.context.preferences.addons["blender-for-unrealengine"].preferences
	for socket in GetSocketDesiredChild(obj):
		if GetShouldRescaleSocket() == True:
			socket.delta_scale *= GetRescaleSocketFactor()
	
		if addon_prefs.staticSocketsAdd90X == True:
			savedScale = socket.scale.copy()
			savedLocation = socket.location.copy()
			AddMat = mathutils.Matrix.Rotation(math.radians(90.0), 4, 'X')
			socket.matrix_world = socket.matrix_world @ AddMat
			socket.scale = savedScale
			socket.location = savedLocation
	
def AddSocketsTempName(obj):
	#Add _UE4Socket_TempName at end
	
	for socket in GetSocketDesiredChild(obj):
		socket.name += "_UE4Socket_TempName"
		
def RemoveDuplicatedSocketsTempName(obj):
	#Remove _UE4Socket_TempName at end
	
	for socket in GetSocketDesiredChild(obj):
		ToRemove = "_UE4Socket_TempName.xxx"
		socket.name = socket.name[:-len(ToRemove)]
	
def RemoveSocketsTempName(obj):
	#Remove _UE4Socket_TempName at end
	for socket in GetSocketDesiredChild(obj):
		ToRemove = "_UE4Socket_TempName"
		socket.name = socket.name[:-len(ToRemove)]
		

def GetShouldRescaleRig():
	#This will return if the rig should be rescale.
	
	addon_prefs = bpy.context.preferences.addons["blender-for-unrealengine"].preferences
	if addon_prefs.rescaleFullRigAtExport == "auto":
		if math.isclose(bpy.context.scene.unit_settings.scale_length, 0.01, rel_tol=1e-5):

			return False #False because that useless to rescale at 1 :v
		else:
			return True
	if addon_prefs.rescaleFullRigAtExport == "custom_rescale":
		return True
	if addon_prefs.rescaleFullRigAtExport == "dont_rescale":
		return False
	return False
	
def GetRescaleRigFactor():
	#This will return the rescale factor.
	
	addon_prefs = bpy.context.preferences.addons["blender-for-unrealengine"].preferences
	if addon_prefs.rescaleFullRigAtExport == "auto":
		return 100 * bpy.context.scene.unit_settings.scale_length
	else:
		return addon_prefs.newRigScale #rigRescaleFactor
		
		
def GetShouldRescaleSocket():
	#This will return if the socket should be rescale.
	
	addon_prefs = bpy.context.preferences.addons["blender-for-unrealengine"].preferences
	if addon_prefs.rescaleSocketsAtExport == "auto":
		if bpy.context.scene.unit_settings.scale_length == 0.01:
			return False #False because that useless to rescale at 1 :v
		else:
			return True
	if addon_prefs.rescaleSocketsAtExport == "custom_rescale":
		return True
	if addon_prefs.rescaleSocketsAtExport == "dont_rescale":
		return False
	return False
		
def GetRescaleSocketFactor():
	#This will return the rescale factor.
	
	addon_prefs = bpy.context.preferences.addons["blender-for-unrealengine"].preferences
	if addon_prefs.rescaleSocketsAtExport == "auto":
		return 1/(100*bpy.context.scene.unit_settings.scale_length)
	else:
		return addon_prefs.staticSocketsImportedSize #socketRescaleFactor

def ExportSingleFbxAction(originalScene, dirpath, filename, obj, targetAction, actionType):
	'''
	#####################################################
			#SKELETAL ACTION
	#####################################################
	'''
	#Export a single action like a animation or pose
	
	scene = bpy.context.scene
	addon_prefs = bpy.context.preferences.addons["blender-for-unrealengine"].preferences
	
	filename = ValidFilenameForUnreal(filename)
	curr_time = time.perf_counter()
	
	if obj.animation_data is None:
		obj.animation_data_create()
	userAction = obj.animation_data.action #Save current action
	userAction_extrapolation = obj.animation_data.action_extrapolation
	userAction_blend_type = obj.animation_data.action_blend_type
	userAction_influence = obj.animation_data.action_influence


	if	bpy.ops.object.mode_set.poll():
		bpy.ops.object.mode_set(mode='OBJECT')
		
	
	SelectParentAndDesiredChilds(obj)
	DuplicateSelect()

	BaseTransform = obj.matrix_world.copy()
	active = bpy.context.view_layer.objects.active
	if active.ExportAsProxy == True:
		ApplyProxyData(active)	
		
	scene.frame_start = GetDesiredActionStartEndTime(active, targetAction)[0]
	scene.frame_end = GetDesiredActionStartEndTime(active, targetAction)[1]

	if addon_prefs.bakeArmatureAction == True:
		BakeArmatureAnimation(active, scene.frame_start, scene.frame_end)
	
	ApplyExportTransform(active)
	
	#This will recale the rig and unit scale to get a root bone egal to 1
	ShouldRescaleRig = GetShouldRescaleRig()
	if ShouldRescaleRig == True:
	
		rrf = GetRescaleRigFactor() #rigRescaleFactor
		savedUnitLength = bpy.context.scene.unit_settings.scale_length
		bpy.context.scene.unit_settings.scale_length *= 1/rrf
		ApplySkeletalExportScale(active, rrf)
		RescaleAllActionCurve(rrf)
		for selected in bpy.context.selected_objects:
			if selected.type == "MESH":
				RescaleShapeKeysCurve(selected, 1/rrf)
		RescaleSelectCurveHook(1/rrf)
		ResetArmaturePose(active)
		RescaleRigConsraints(active, rrf)
	
	if (scene.is_nla_tweakmode == True):
		active.animation_data.use_tweak_mode = False #animation_data.action is ReadOnly with tweakmode in 2.8
	
	active.animation_data.action = targetAction #Apply desired action and reset NLA
	if addon_prefs.ignoreNLAForAction == True:
		active.animation_data.action_extrapolation = 'HOLD'
		active.animation_data.action_blend_type = 'REPLACE'
		active.animation_data.action_influence = 1
		
	
	absdirpath = bpy.path.abspath(dirpath)
	VerifiDirs(absdirpath)
	fullpath = os.path.join( absdirpath , filename )
	
	#Set rename temporarily the Armature as "Armature"
	oldArmatureName = RenameArmatureAsExportName(active)
	
	bpy.ops.export_scene.fbx(
		filepath=fullpath,
		check_existing=False,
		use_selection=True,
		global_scale=GetObjExportScale(active),
		object_types={'ARMATURE', 'EMPTY', 'MESH'},
		use_custom_props=addon_prefs.exportWithCustomProps,
		mesh_smooth_type="FACE",
		add_leaf_bones=False,
		use_armature_deform_only=active.exportDeformOnly,
		bake_anim=True,
		bake_anim_use_nla_strips=False,
		bake_anim_use_all_actions=False,
		bake_anim_force_startend_keying=True,
		bake_anim_step=GetAnimSample(active),
		bake_anim_simplify_factor=active.SimplifyAnimForExport,
		use_metadata=addon_prefs.exportWithMetaData,
		primary_bone_axis = active.exportPrimaryBaneAxis,
		secondary_bone_axis = active.exporSecondaryBoneAxis,	
		axis_forward = active.exportAxisForward,
		axis_up = active.exportAxisUp,
		bake_space_transform = False
		)

	#Reset armature name
	ResetArmatureName(active, oldArmatureName, )
	
	ResetArmaturePose(obj)
		
	obj.animation_data.action = userAction #Resets previous action and NLA
	if addon_prefs.ignoreNLAForAction == True:
		obj.animation_data.action_extrapolation = userAction_extrapolation
		obj.animation_data.action_blend_type = userAction_blend_type
		obj.animation_data.action_influence = userAction_influence
	
	
	#Reset Transform
	obj.matrix_world = BaseTransform
	
	##This will recale the rig and unit scale to get a root bone egal to 1
	if ShouldRescaleRig == True:
		#Reset Curve an unit
		bpy.context.scene.unit_settings.scale_length = savedUnitLength
		RescaleAllActionCurve(1/rrf)

	bpy.ops.object.delete()
	
	exportTime = time.perf_counter()-curr_time
	MyAsset = originalScene.UnrealExportedAssetsList.add()
	MyAsset.assetName = filename
	MyAsset.assetType = actionType
	MyAsset.exportPath = absdirpath
	MyAsset.exportTime = exportTime
	MyAsset.object = obj
	return MyAsset

def ExportSingleFbxNLAAnim(originalScene, dirpath, filename, obj):
	'''
	#####################################################
			#NLA ANIMATION
	#####################################################
	'''
	#Export a single NLA Animation

	scene = bpy.context.scene
	addon_prefs = bpy.context.preferences.addons["blender-for-unrealengine"].preferences
	
	filename = ValidFilenameForUnreal(filename)
	curr_time = time.perf_counter()

	SelectParentAndDesiredChilds(obj)
	DuplicateSelect()
	BaseTransform = obj.matrix_world.copy()
	active = bpy.context.view_layer.objects.active
	if active.ExportAsProxy == True:
		ApplyProxyData(active)
	
	if addon_prefs.bakeArmatureAction == True:
		BakeArmatureAnimation(active, scene.frame_start, scene.frame_end)
		
	ApplyExportTransform(active)

	##This will recale the rig and unit scale to get a root bone egal to 1
	ShouldRescaleRig = GetShouldRescaleRig()
	if ShouldRescaleRig == True:
	
		rrf = GetRescaleRigFactor() #rigRescaleFactor
		savedUnitLength = bpy.context.scene.unit_settings.scale_length
		bpy.context.scene.unit_settings.scale_length *= 1/rrf
		ApplySkeletalExportScale(active, rrf)
		RescaleAllActionCurve(rrf)
		for selected in bpy.context.selected_objects:
			if selected.type == "MESH":
				RescaleShapeKeysCurve(selected, 1/rrf)
		RescaleSelectCurveHook(1/rrf)
		ResetArmaturePose(active)
		RescaleRigConsraints(active, rrf)
	
	scene.frame_start += active.StartFramesOffset
	scene.frame_end += active.EndFramesOffset
	absdirpath = bpy.path.abspath(dirpath)
	VerifiDirs(absdirpath)
	fullpath = os.path.join( absdirpath , filename )

	#Set rename temporarily the Armature as "Armature"
	oldArmatureName = RenameArmatureAsExportName(active)

	bpy.ops.export_scene.fbx(
		filepath=fullpath,
		check_existing=False,
		use_selection=True,
		global_scale=GetObjExportScale(active),
		object_types={'ARMATURE', 'EMPTY', 'MESH'},
		use_custom_props=addon_prefs.exportWithCustomProps,
		add_leaf_bones=False,
		use_armature_deform_only=active.exportDeformOnly,
		bake_anim=True,
		bake_anim_use_nla_strips=False,
		bake_anim_use_all_actions=False,
		bake_anim_force_startend_keying=True,
		bake_anim_step=GetAnimSample(active),
		bake_anim_simplify_factor=active.SimplifyAnimForExport,
		use_metadata=addon_prefs.exportWithMetaData,
		primary_bone_axis = active.exportPrimaryBaneAxis,
		secondary_bone_axis = active.exporSecondaryBoneAxis,	
		axis_forward = active.exportAxisForward,
		axis_up = active.exportAxisUp,
		bake_space_transform = False
		)		
		
	ResetArmaturePose(active)
	scene.frame_start -= active.StartFramesOffset
	scene.frame_end -= active.EndFramesOffset
	exportTime = time.perf_counter()-curr_time

	#Reset armature name
	ResetArmatureName(active, oldArmatureName)
	
	ResetArmaturePose(obj)
	
	#Reset Transform
	obj.matrix_world = BaseTransform
	
	##This will recale the rig and unit scale to get a root bone egal to 1
	if ShouldRescaleRig == True:
		#Reset Curve an unit
		bpy.context.scene.unit_settings.scale_length = savedUnitLength
		RescaleAllActionCurve(1/rrf)

	bpy.ops.object.delete()

	MyAsset = originalScene.UnrealExportedAssetsList.add()
	MyAsset.assetName = filename
	MyAsset.assetType = "NlAnim"
	MyAsset.exportPath = absdirpath
	MyAsset.exportTime = exportTime
	MyAsset.object = obj
	return MyAsset



def ExportSingleAlembicAnimation(originalScene, dirpath, filename, obj):
	'''
	#####################################################
			#ALEMBIC ANIMATION
	#####################################################
	'''
	#Export a single alembic animation

	scene = bpy.context.scene
	filename = ValidFilenameForUnreal(filename)
	curr_time = time.perf_counter()
	if	bpy.ops.object.mode_set.poll():
		bpy.ops.object.mode_set(mode = 'OBJECT')

	SelectParentAndDesiredChilds(obj)

	scene.frame_start += obj.StartFramesOffset
	scene.frame_end += obj.EndFramesOffset
	absdirpath = bpy.path.abspath(dirpath)
	VerifiDirs(absdirpath)
	fullpath = os.path.join( absdirpath , filename )

	##Export
	bpy.ops.wm.alembic_export(
		filepath=fullpath,
		check_existing=False,
		selected=True,
		triangulate=False,
		)

	scene.frame_start -= obj.StartFramesOffset
	scene.frame_end -= obj.EndFramesOffset
	exportTime = time.perf_counter()-curr_time

	MyAsset = originalScene.UnrealExportedAssetsList.add()
	MyAsset.assetName = filename
	MyAsset.assetType = "Alembic"
	MyAsset.exportPath = absdirpath
	MyAsset.exportTime = exportTime
	MyAsset.object = obj
	return MyAsset


def ExportSingleStaticMeshCollection(originalScene, dirpath, filename, collectionName):
	'''
	#####################################################
			#COLLECTION
	#####################################################
	'''
	#create collection and export it
	obj = bpy.data.objects.new( "EmptyCollectionForUnrealExport_Temp", None )
	bpy.context.scene.collection.objects.link( obj )
	obj.instance_type = 'COLLECTION'
	obj.instance_collection = bpy.data.collections[collectionName]
	ExportSingleStaticMesh(originalScene, dirpath, filename, obj)
	
	#Remove the created collection
	SelectSpecificObject(obj)
	bpy.ops.object.delete()	 
	
	
def ExportSingleStaticMesh(originalScene, dirpath, filename, obj):
	'''
	#####################################################
			#STATIC MESH
	#####################################################
	'''
	#Export a single Mesh

	scene = bpy.context.scene
	addon_prefs = bpy.context.preferences.addons["blender-for-unrealengine"].preferences
	
	filename = ValidFilenameForUnreal(filename)
	curr_time = time.perf_counter()
	
	if	bpy.ops.object.mode_set.poll():
		bpy.ops.object.mode_set(mode = 'OBJECT')
	
	SelectParentAndDesiredChilds(obj)
	AddSocketsTempName(obj)
	DuplicateSelect()
	ApplyNeededModifierToSelect()

	active = bpy.context.view_layer.objects.active
	

	if addon_prefs.correctExtremUVScale == True:
		bpy.ops.object.mode_set(mode = 'EDIT')
		CorrectExtremeUV(2)
		bpy.ops.object.mode_set(mode = 'OBJECT')
		
	UpdateNameHierarchy(GetAllCollisionAndSocketsObj(bpy.context.selected_objects))
	
	ApplyExportTransform(active)
	

	absdirpath = bpy.path.abspath(dirpath)
	VerifiDirs(absdirpath)
	fullpath = os.path.join( absdirpath , filename )
	meshType = GetAssetType(active)
	
	SetSocketsExportTransform(active)
	
	RemoveDuplicatedSocketsTempName(active)
			

	bpy.ops.export_scene.fbx(
		filepath=fullpath,
		check_existing=False,
		use_selection=True,
		global_scale=GetObjExportScale(active),
		object_types={'EMPTY', 'CAMERA', 'LIGHT', 'MESH', 'OTHER'},
		use_custom_props=addon_prefs.exportWithCustomProps,
		mesh_smooth_type="FACE",
		add_leaf_bones=False,
		use_armature_deform_only=active.exportDeformOnly,
		bake_anim=False,
		use_metadata=addon_prefs.exportWithMetaData,
		primary_bone_axis = active.exportPrimaryBaneAxis,
		secondary_bone_axis = active.exporSecondaryBoneAxis,	
		axis_forward = active.exportAxisForward,
		axis_up = active.exportAxisUp,
		bake_space_transform = False
		)
		
	bpy.ops.object.delete()
	RemoveSocketsTempName(obj)
		

	
	
	exportTime = time.perf_counter()-curr_time

	MyAsset = originalScene.UnrealExportedAssetsList.add()
	MyAsset.assetName = filename
	MyAsset.assetType = meshType
	MyAsset.exportPath = absdirpath
	MyAsset.exportTime = exportTime
	MyAsset.object = obj
	return MyAsset
	
def ExportSingleSkeletalMesh(originalScene, dirpath, filename, obj):
	'''
	#####################################################
			#SKELETAL MESH
	#####################################################
	'''
	#Export a single Mesh

	scene = bpy.context.scene
	addon_prefs = bpy.context.preferences.addons["blender-for-unrealengine"].preferences
	
	filename = ValidFilenameForUnreal(filename)
	curr_time = time.perf_counter()
	
	if	bpy.ops.object.mode_set.poll():
		bpy.ops.object.mode_set(mode = 'OBJECT')

	
	SelectParentAndDesiredChilds(obj)
	AddSocketsTempName(obj)
	DuplicateSelect()	
		
	ApplyNeededModifierToSelect()
	
	if addon_prefs.correctExtremUVScale == True:
		SavedSelect = GetCurrentSelect()
		if GoToMeshEditMode() == True:
			CorrectExtremeUV(2)
		bpy.ops.object.mode_set(mode = 'OBJECT')
		SetCurrentSelect(SavedSelect)
		
		
		
		
	UpdateNameHierarchy(GetAllCollisionAndSocketsObj(bpy.context.selected_objects))
	active = bpy.context.view_layer.objects.active
	if active.ExportAsProxy == True:
		ApplyProxyData(active)
	
	ApplyExportTransform(active)
	
	##This will recale the rig and unit scale to get a root bone egal to 1
	ShouldRescaleRig = GetShouldRescaleRig()
	if ShouldRescaleRig == True:
				
		rrf = GetRescaleRigFactor() #rigRescaleFactor
		savedUnitLength = bpy.context.scene.unit_settings.scale_length
		bpy.context.scene.unit_settings.scale_length *= 1/rrf
		ApplySkeletalExportScale(active, rrf)
		

	absdirpath = bpy.path.abspath(dirpath)
	VerifiDirs(absdirpath)
	fullpath = os.path.join( absdirpath , filename )
	meshType = GetAssetType(active)
			
	SetSocketsExportTransform(active)
	RemoveDuplicatedSocketsTempName(active)

	
	#Set rename temporarily the Armature as "Armature"
	oldArmatureName = RenameArmatureAsExportName(active)
	
	RemoveAllConsraints(active)
	bpy.context.object.data.pose_position = 'REST'
	
	bpy.ops.export_scene.fbx(
		filepath=fullpath,
		check_existing=False,
		use_selection=True,
		global_scale=GetObjExportScale(active),
		object_types={'ARMATURE', 'EMPTY', 'CAMERA', 'LIGHT', 'MESH', 'OTHER'},
		use_custom_props=addon_prefs.exportWithCustomProps,
		mesh_smooth_type="FACE",
		add_leaf_bones=False,
		use_armature_deform_only=active.exportDeformOnly,
		bake_anim=False,
		use_metadata=addon_prefs.exportWithMetaData,
		primary_bone_axis = active.exportPrimaryBaneAxis,
		secondary_bone_axis = active.exporSecondaryBoneAxis,	
		axis_forward = active.exportAxisForward,
		axis_up = active.exportAxisUp,
		bake_space_transform = False
		)
	
	##This will recale the rig and unit scale to get a root bone egal to 1
	if ShouldRescaleRig == True:
		#Reset Curve an unit
		bpy.context.scene.unit_settings.scale_length = savedUnitLength
		
	#Reset armature name

	ResetArmatureName(active, oldArmatureName)
	bpy.ops.object.delete()
	
	RemoveSocketsTempName(obj)
	
	exportTime = time.perf_counter()-curr_time
	MyAsset = originalScene.UnrealExportedAssetsList.add()
	MyAsset.assetName = filename
	MyAsset.assetType = meshType
	MyAsset.exportPath = absdirpath
	MyAsset.exportTime = exportTime
	MyAsset.object = obj
	return MyAsset


def ExportSingleFbxCamera(originalScene, dirpath, filename, obj):
	'''
	#####################################################
			#CAMERA
	#####################################################
	'''
	#Export single camera

	scene = bpy.context.scene
	addon_prefs = bpy.context.preferences.addons["blender-for-unrealengine"].preferences
	
	filename = ValidFilename(filename)
	if obj.type != 'CAMERA':
		return;
	curr_time = time.perf_counter()
	if	bpy.ops.object.mode_set.poll():
		bpy.ops.object.mode_set(mode = 'OBJECT')
	

	#Select and rescale camera for export
	bpy.ops.object.select_all(action='DESELECT')
	SelectSpecificObject(obj)
	
	obj.delta_scale*=0.01
	if obj.animation_data is not None:
		action = obj.animation_data.action
		scene.frame_start = GetDesiredActionStartEndTime(obj, action)[0]
		scene.frame_end = GetDesiredActionStartEndTime(obj, action)[1]

	absdirpath = bpy.path.abspath(dirpath)
	VerifiDirs(absdirpath)
	fullpath = os.path.join( absdirpath , filename )

	bpy.ops.export_scene.fbx(
		filepath=fullpath,
		check_existing=False,
		use_selection=True,
		global_scale=GetObjExportScale(obj),
		object_types={'CAMERA'},
		use_custom_props=addon_prefs.exportWithCustomProps,
		add_leaf_bones=False,
		use_armature_deform_only=obj.exportDeformOnly,
		bake_anim=True,
		bake_anim_use_nla_strips=False,
		bake_anim_use_all_actions=False,
		bake_anim_force_startend_keying=True,
		bake_anim_step=GetAnimSample(obj),
		bake_anim_simplify_factor=obj.SimplifyAnimForExport,
		use_metadata=addon_prefs.exportWithMetaData,
		primary_bone_axis = obj.exportPrimaryBaneAxis,
		secondary_bone_axis = obj.exporSecondaryBoneAxis,	
		axis_forward = obj.exportAxisForward,
		axis_up = obj.exportAxisUp,
		bake_space_transform = False
		)

	#Reset camera scale
	obj.delta_scale*=100

	exportTime = time.perf_counter()-curr_time

	MyAsset = originalScene.UnrealExportedAssetsList.add()
	MyAsset.assetName = filename
	MyAsset.assetType = "Camera"
	MyAsset.exportPath = absdirpath
	MyAsset.exportTime = exportTime
	MyAsset.object = obj
	return MyAsset

def ExportSingleAdditionalTrackCamera(dirpath, filename, obj):
	#Export additional camera track for ue4
	#FocalLength
	#FocusDistance
	#Aperture

	absdirpath = bpy.path.abspath(dirpath)
	VerifiDirs(absdirpath)
	AdditionalTrack = bfu_WriteText.WriteSingleCameraAdditionalTrack(obj)
	return bfu_WriteText.ExportSingleText(AdditionalTrack, absdirpath, filename)

def ExportSingleAdditionalParameterMesh(dirpath, filename, obj):
	#Export additional parameter from static and skeletal mesh track for ue4
	#SocketsList

	absdirpath = bpy.path.abspath(dirpath)
	VerifiDirs(absdirpath)
	AdditionalTrack = bfu_WriteText.WriteSingleMeshAdditionalParameter(obj)
	return bfu_WriteText.ExportSingleConfigParser(AdditionalTrack, absdirpath, filename)